import numpy as np
import matplotlib.pyplot as plt
#模型函数
def model(x,theta):
    return x.dot(theta)
#代价函数
def costfunc(h,y):
    # return 1/(2*len(train_h))*(train_h-y).T.dot(train_h-y)
    return 0.5*np.mean((h-y)**2)
#梯度下降
#x:X
#y：标签
#alpha:梯度下降的学习率
#iter0：梯度下降的循环次数
def grad(x,y,alpha=0.02,iter0=5000):
    #m:样本点个数
    #n:参数个数
    m,n=x.shape
    # theta：初始theta
    theta=np.zeros(n)
    #存放代价函数值的数组
    J=np.zeros(iter0)
    for i in range(iter0):
        #当前theta的预测值
        h=model(x,theta)
        #当前theta的代价函数值
        J[i]=costfunc(h,y)
        #梯度、导数值
        deltatheta=1/m*x.T.dot(h-y)
        #更新theta
        theta-=alpha*deltatheta
    return theta,J,h

if __name__ == '__main__':
    #加载数据
    data=np.loadtxt('ex1data1.txt',delimiter=',')
    #获得特征
    x=data[:,:-1]
    #获得标签
    y=data[:,-1]
    #在特征向量前拼接1
    X=np.c_[np.ones(len(x)),x]
    #调用函数训练模型
    theta,J,h=grad(X,y)
    #画代价函数值图像
    plt.plot(J)
    plt.show()
    #画所有样本点：红色
    plt.scatter(x,y,c='r')
    #画出预测函数：黄色
    plt.plot(x,h,c='y')
    plt.show()